package com.zts.base.spring.interceptor;

import com.zts.base.exception.DuplicateKeyException;
import com.zts.base.exception.ExceptionResponse;
import com.zts.base.exception.Exceptions;
import com.zts.base.exception.ServiceException;
import com.zts.util.JsonUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Created by Zhangkh on 2017/6/12.
 */
@ControllerAdvice
public class MyExceptionHandler {
    private static Logger logger = LoggerFactory.getLogger(MyExceptionHandler.class);

    private void resolveExceptionBefore(Exception e) {
        if (e instanceof org.springframework.dao.DuplicateKeyException) {
            logger.warn("发生记录重复异常");
            logger.warn(e.getMessage());
            throw new DuplicateKeyException("记录已存在或主键冲突");
        }
    }


    @ExceptionHandler(value = Throwable.class)
    @ResponseBody
    //@ResponseStatus(HttpStatus.BAD_REQUEST)
    public ExceptionResponse resolveException(HttpServletRequest httpServletRequest,
                                              HttpServletResponse httpServletResponse, Exception e) {
        logger.debug("using MyExceptionHandler to handle exception");
        try {
            resolveExceptionBefore(e);
            //return  handleException(httpServletRequest, httpServletResponse, e);
        } catch (Exception ex) {
            e = ex;
        }
        return handleException(httpServletRequest, httpServletResponse, e);
    }

    public ExceptionResponse handleException(HttpServletRequest httpServletRequest,
                                             HttpServletResponse httpServletResponse, Exception e) {
        int status = 400;
        ExceptionResponse er = new ExceptionResponse();
        if (e instanceof ServiceException) {
            status = getStatus(e).value();
            er.setCode(((ServiceException) e).getCode());
        } else {
            er.setCode("");
        }
        er.setStatus(status);
        er.setMessage(e.getMessage());
        er.setException(e.getClass().getName());

        /*  使用response返回    */
        httpServletResponse.setStatus(status); //设置状态码
        httpServletResponse.setContentType(MediaType.APPLICATION_JSON_VALUE); //设置ContentType
        //httpServletResponse.setCharacterEncoding("UTF-8"); //避免乱码
        httpServletResponse.setHeader("Cache-Control", "no-cache, must-revalidate");
        try {
            logger.warn("异常信息：" + er.toString());
            // httpServletResponse.getWriter().write(JsonUtil.toJsonString(er));
        } catch (Exception ex) {

        }
        return er;
    }

    private HttpStatus getStatus(Exception ex) {
        HttpStatus status = HttpStatus.INTERNAL_SERVER_ERROR;
        boolean checkAnnotation = true;

        if (ex instanceof ServiceException) {
            ServiceException sex = (ServiceException) ex;
            try {
                if (sex.getHttpStatus() != null) {
                    status = HttpStatus.valueOf(sex.getHttpStatus());
                    checkAnnotation = false;
                }
            } catch (Exception e) {
                Exceptions.catching(e);
            }
        }

        if (checkAnnotation) {
            ResponseStatus rs = AnnotationUtils.findAnnotation(ex.getClass(), ResponseStatus.class);
            if (rs != null) {
                status = rs.code();
            }
        }

        return status;
    }
}
